﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ivi.Visa;
using NationalInstruments.Visa;

namespace DebugTools
{
    public partial class Ins : Form
    {
        public string Source_ID, EL1_ID, EL2_ID;
        public TextBox tbIndex;

        private TreeNode ndGpib;
        private TreeNode ndTcpip;
        private TreeNode ndUSB;
        private string m_sIniFilePath;
        private IniFiles m_iniFile;
        private System.Collections.Specialized.NameValueCollection m_InsInfo;

        public Ins()
        {
            InitializeComponent();

            tbIndex = textBox0;
            ndGpib = new TreeNode("GPIB");
            ndTcpip = new TreeNode("TCP/IP");
            ndUSB = new TreeNode("USB");
            m_sIniFilePath = System.IO.Path.Combine(Application.StartupPath, "Ins.ini");
            m_iniFile = new IniFiles(m_sIniFilePath);
            m_InsInfo = new System.Collections.Specialized.NameValueCollection();
            m_iniFile.ReadSectionValues("Instruments", m_InsInfo);
        }

        protected override void Dispose(bool disposing)
        {
            if(disposing)
            {
                if(components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        private void AddToResourceTree()
        {
            if (ndGpib.Nodes.Count != 0)
                InsTreeView.Nodes.Add(ndGpib);
            if (ndTcpip.Nodes.Count != 0)
                InsTreeView.Nodes.Add(ndTcpip);
            if (ndUSB.Nodes.Count != 0)
                InsTreeView.Nodes.Add(ndUSB);
        }

        private void AddToResourceNode(string resourceName, HardwareInterfaceType intType)
        {
            int nIndex = GetCollectionIndex(resourceName);
            TreeNode node = new TreeNode(resourceName);

            node.ToolTipText = resourceName;
            if (nIndex > -1)
                node.Text = m_InsInfo[nIndex];
            else
                m_InsInfo.Add(resourceName, resourceName);
            
            switch(intType)
            {
                case HardwareInterfaceType.Gpib:
                    ndGpib.Nodes.Add(node);
                    break;
                case HardwareInterfaceType.Tcp:
                    ndTcpip.Nodes.Add(node);
                    break;
                case HardwareInterfaceType.Usb:
                    ndUSB.Nodes.Add(node);
                    break;
                default:
                    break;
            }
        }

        private void FindResources()
        {
            using(var rm = new ResourceManager())
            {
                try
                {
                    IEnumerable<string> resources = rm.Find("?*");
                    foreach(string s in resources)
                    {
                        ParseResult parseResult = rm.Parse(s);
                        AddToResourceNode(s, parseResult.InterfaceType);
                    }
                    AddToResourceTree();
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void cleanResourceNodes()
        {
            ndGpib.Nodes.Clear();
            ndTcpip.Nodes.Clear();
            ndUSB.Nodes.Clear();
        }

        private int GetCollectionIndex(string key)
        {
            for (int i = 0; i < m_InsInfo.Count; i++)
            {
                if (key == m_InsInfo.AllKeys[i])
                    return i;
            }
            return -1;
        }

        private void GetChildNodeInfo(TreeNode node0)
        {
            TreeNode node = node0.FirstNode;
            if (node != null)
            {
                if (GetCollectionIndex(node.ToolTipText) > -1)
                    m_InsInfo.Set(node.ToolTipText, node.Text);
                else
                    m_InsInfo.Add(node.ToolTipText, node.Text);
            }
            while(node != node0.LastNode)
            {
                node = node.NextNode;
                if (GetCollectionIndex(node.ToolTipText) > -1)
                    m_InsInfo.Set(node.ToolTipText, node.Text);
                else
                    m_InsInfo.Add(node.ToolTipText, node.Text);
            }
            
        }

        private void SaveInsInfo()
        {
            GetChildNodeInfo(ndGpib);
            GetChildNodeInfo(ndTcpip);
            GetChildNodeInfo(ndUSB);
            m_iniFile.EraseSection("Instruments");
            int nCount = m_InsInfo.Count;
            string key, value;
            for (int i = 0; i < m_InsInfo.Count; i++)
            {
                key = m_InsInfo.AllKeys[i];
                value = m_InsInfo[i];
                m_iniFile.WriteString("Instruments", m_InsInfo.AllKeys[i], m_InsInfo[i]);
            }
        }

        private void Ins_Load(object sender, EventArgs e)
        {
            InsTreeView.Nodes.Clear();
            cleanResourceNodes();
            FindResources();
            InsTreeView.ExpandAll();
        }

        private void Ins_FormClosed(object sender, FormClosedEventArgs e)
        {
            SaveInsInfo();
            Source_ID = textBox_AC.Text;
            EL1_ID = textBox_EL1.Text;
            EL2_ID = textBox_EL2.Text;
        }

        private void InsTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            string str = e.Node.ToolTipText;
            tbIndex.Text = e.Node.ToolTipText;
            Visa ins;
            if(GetCollectionIndex(str) > -1)
            {
                ins = new Visa(str);
                textBox_EL2.Text = ins.Query("*IDN?\n");
            }
        }

        private void textBox_AC_Click(object sender, EventArgs e)
        {
            tbIndex = textBox_AC;
        }

        private void textBox_EL1_Click(object sender, EventArgs e)
        {
            tbIndex = textBox_EL1;
        }

        private void textBox_EL2_Click(object sender, EventArgs e)
        {
            tbIndex = textBox_EL2;
        }
    }
}
